package top.lixunda.ecommerce.server.good.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import top.lixunda.common.utils.ObjectValidators;
import top.lixunda.ecommerce.server.business.BaseServiceImpl;
import top.lixunda.ecommerce.server.business.api.entity.cache.CacheAdminUser;
import top.lixunda.ecommerce.server.good.api.entity.db.SysStoreCategoryDO;
import top.lixunda.ecommerce.server.good.api.entity.dto.StoreCategoryInsertDTO;
import top.lixunda.ecommerce.server.good.api.entity.dto.StoreCategoryUpdateDTO;
import top.lixunda.ecommerce.server.good.mapper.SysStoreCategoryMapper;
import top.lixunda.ecommerce.server.good.service.ISysStoreCategoryService;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 店铺类别静态表，管理员进行管理 服务实现类
 * </p>
 *
 * @author Xumda
 * @since 2019-12-18
 */
@Service
public class SysStoreCategoryServiceImpl
        extends BaseServiceImpl<SysStoreCategoryMapper, SysStoreCategoryDO>
        implements ISysStoreCategoryService {

    @Autowired
    public SysStoreCategoryServiceImpl() {
    }

    /**
     * 添加一个店铺分类
     *
     * @param storeCategoryInsertDTO 新添加的店铺分类数据
     * @return 是否添加成功
     */
    @Override
    public boolean insertStoreCategory(StoreCategoryInsertDTO storeCategoryInsertDTO) {
        if (ObjectValidators.isEmpty(storeCategoryInsertDTO)) {
            throw getAppException("参数不能为空");
        }
        CacheAdminUser cacheAdminUser = currentAdminUserCacheNotNull();
        boolean isRoot = !(storeCategoryInsertDTO.getParentId() != null && storeCategoryInsertDTO.getParentId() > 0);
        SysStoreCategoryDO sysStoreCategoryDO = new SysStoreCategoryDO();
        LocalDateTime localDateTime = LocalDateTime.now();
        sysStoreCategoryDO
                .setIsLeaf(SysStoreCategoryDO.LEAF_IS)
                .setIsRoot(isRoot ? SysStoreCategoryDO.ROOT_IS : SysStoreCategoryDO.ROOT_NOT)
                .setDescription(storeCategoryInsertDTO.getDescription())
                .setName(storeCategoryInsertDTO.getName())
                .setParent(isRoot ? 0 : storeCategoryInsertDTO.getParentId())
                .setCreateTime(localDateTime)
                .setUpdateTime(localDateTime)
                .setCreateUserId(cacheAdminUser.getAccount())
                .setCreateUerName(cacheAdminUser.getName())
                .setUpdateUserId(cacheAdminUser.getAccount())
                .setUpdateUerName(cacheAdminUser.getName())
                .setRemark(storeCategoryInsertDTO.getRemark());
        return this.save(sysStoreCategoryDO);
    }

    /**
     * 更新一个店铺分类
     *
     * @param storeCategoryUpdateDTO 需要更新的店铺分类数据
     * @return 是否更新成功
     */
    @Override
    public boolean updateStoreCategory(StoreCategoryUpdateDTO storeCategoryUpdateDTO) {
        if (ObjectValidators.isEmpty(storeCategoryUpdateDTO)) {
            throw getAppException("参数不能为空");
        }
        CacheAdminUser cacheAdminUser = currentAdminUserCacheNotNull();
        SysStoreCategoryDO sysStoreCategoryDO = this.getById(storeCategoryUpdateDTO.getId());
        if (ObjectValidators.isEmpty(sysStoreCategoryDO)) {
            throw getAppException("分类信息不存在");
        }
        sysStoreCategoryDO.setName(storeCategoryUpdateDTO.getName())
                .setDescription(storeCategoryUpdateDTO.getDescription())
                .setRemark(storeCategoryUpdateDTO.getRemark())
                .setUpdateTime(LocalDateTime.now())
                .setUpdateUserId(cacheAdminUser.getAccount())
                .setUpdateUerName(cacheAdminUser.getName());
        return this.updateById(sysStoreCategoryDO);
    }

    /**
     * 根据id删除店铺分类，只删除该节点，其子节点全部放到父节点中去
     *
     * @param id 店铺分类id
     * @return 是否删除成功
     */
    @Override
    public boolean removeStoreCategoryById(Integer id) {
        if (ObjectValidators.isEmpty(id)) {
            throw getAppException("店铺分类id不能为空");
        }
        currentAdminUserCacheNotNull();
        SysStoreCategoryDO sysStoreCategoryDO = this.getById(id);
        if (ObjectValidators.isEmpty(sysStoreCategoryDO)) {
            throw getAppException("分类信息不存在");
        }
        // 把子节点放到父节点中去
        List<SysStoreCategoryDO> list = this.list(new LambdaQueryWrapper<SysStoreCategoryDO>()
                .eq(SysStoreCategoryDO::getParent, id));
        if (ObjectValidators.isNotEmpty(list)) {
            List<Integer> changeIds = list.stream()
                    .filter(Objects::nonNull)
                    .map(SysStoreCategoryDO::getId)
                    .collect(Collectors.toList());
            if (ObjectValidators.isNotEmpty(changeIds)) {
                this.update(new LambdaUpdateWrapper<SysStoreCategoryDO>()
                        .set(SysStoreCategoryDO::getParent, sysStoreCategoryDO.getParent())
                        .set(SysStoreCategoryDO::getIsRoot, sysStoreCategoryDO.getIsRoot())
                        .in(SysStoreCategoryDO::getId, changeIds));
            }
        }
        // 移除本身节点
        this.removeById(id);
        return true;
    }

    /**
     * 根据id删除店铺分类，只删除该节点，其子节点全部放到父节点中去
     *
     * @param ids 店铺分类id
     * @return 是否删除成功
     */
    @Override
    public boolean removeStoreCategoryByIds(List<Integer> ids) {
        if (ObjectValidators.isEmpty(ids)) {
            throw getAppException("店铺分类id不能为空");
        }
        for (Integer id : ids) {
            this.removeStoreCategoryById(id);
        }
        return true;
    }

    /**
     * 根据id删除店铺分类，删除包括子节点的所有节点
     *
     * @param id 店铺分类id
     * @return 是否删除成功
     */
    @Override
    public boolean removeStoreCategoryAllById(Integer id) {
        if (ObjectValidators.isEmpty(id)) {
            throw getAppException("店铺分类id不能为空");
        }
        currentAdminUserCacheNotNull();
        SysStoreCategoryDO sysStoreCategoryDO = this.getById(id);
        if (ObjectValidators.isEmpty(sysStoreCategoryDO)) {
            throw getAppException("分类信息不存在");
        }
        // 查询所有子节点
        List<SysStoreCategoryDO> list = new ArrayList<>(128);
        list.add(sysStoreCategoryDO);
        List<Integer> selectIds = Collections.singletonList(id);
        List<SysStoreCategoryDO> tempList;
        while (ObjectValidators.isNotEmpty(selectIds)) {
            tempList = this.list(new LambdaQueryWrapper<SysStoreCategoryDO>()
                    .in(SysStoreCategoryDO::getParent, selectIds));
            list.addAll(tempList);
            selectIds = tempList.stream()
                    .map(SysStoreCategoryDO::getId)
                    .collect(Collectors.toList());
        }
        selectIds = list.stream()
                .filter(Objects::nonNull)
                .map(SysStoreCategoryDO::getId)
                .distinct()
                .collect(Collectors.toList());
        if (ObjectValidators.isNotEmpty(selectIds)) {
            this.removeByIds(selectIds);
        }
        return true;
    }

    /**
     * 根据id删除店铺分类，删除包括子节点的所有节点
     *
     * @param ids 店铺分类id
     * @return 是否删除成功
     */
    @Override
    public boolean removeStoreCategoryAllByIds(List<Integer> ids) {
        if (ObjectValidators.isEmpty(ids)) {
            throw getAppException("店铺分类id不能为空");
        }
        for (Integer id : ids) {
            this.removeStoreCategoryAllById(id);
        }
        return true;
    }

    /**
     * 根据id查询数据
     *
     * @param id 分类id
     * @return 单条分类数据
     */
    @Override
    public SysStoreCategoryDO queryById(Integer id) {
        if (ObjectValidators.isEmpty(id)) {
            throw getAppException("参数id不能为空");
        }
        return this.getById(String.valueOf(id));
    }

    /**
     * 查询所有分类信息
     *
     * @return 所有分类信息
     */
    @Override
    public List<SysStoreCategoryDO> queryAll() {
        return this.list();
    }

    /**
     * 根据父节点id获取子节点id
     *
     * @param id 父节点id
     * @return 所有子节点列表
     */
    @Override
    public List<SysStoreCategoryDO> queryChildrenByParentId(Integer id) {
        if (ObjectValidators.isEmpty(id)) {
            throw getAppException("参数id不能为空");
        }
        // id小于等于零时返回根节点列表
        if (id <= 0) {
            return queryRoots();
        }
        return this.list(
                new LambdaQueryWrapper<SysStoreCategoryDO>()
                        .eq(SysStoreCategoryDO::getParent, id));
    }

    /**
     * 查询根节点
     *
     * @return 根节点列表
     */
    @Override
    public List<SysStoreCategoryDO> queryRoots() {
        return this.list(new LambdaQueryWrapper<SysStoreCategoryDO>()
                .eq(SysStoreCategoryDO::getIsRoot, SysStoreCategoryDO.ROOT_IS));
    }

}
